#include "drv_soft_spi.h"
#include "delay.h"

DEF_STRUCT
	uint32_t cs_pin;
	uint32_t clk_pin;
	uint32_t sdi_pin;
	uint32_t sdo_pin;
	uint8_t  delay_us;
END_DEF_STRUCT(Drv_Soft_Spi_Bus)

#define SPI_CS_SET(pin)		hc32_pin_write(pin,PIN_HIGH)	
#define SPI_CS_CLR(pin)		hc32_pin_write(pin,PIN_LOW)		
#define SPI_SDI_SET(pin)	hc32_pin_write(pin,PIN_HIGH)				
#define SPI_SDI_CLR(pin)	hc32_pin_write(pin,PIN_LOW)	
#define SPI_SCK_SET(pin)	hc32_pin_write(pin,PIN_HIGH)	
#define SPI_SCK_CLR(pin)	hc32_pin_write(pin,PIN_LOW)	
#define SPI_SDO_READ(pin)	hc32_pin_read(pin)	


void drv_soft_spi_write_byte(Drv_Soft_Spi_Bus *spi_bus,uint8_t regAddr,uint8_t data){
	STRUCT(Drv_Soft_Spi_Bus) *spi_bus_t = (STRUCT(Drv_Soft_Spi_Bus) *)spi_bus;
	uint8_t i=0;
	regAddr=regAddr<<1;
	SPI_CS_CLR(spi_bus_t->cs_pin);
	Delay_us(spi_bus_t->delay_us);

	for(i=0;i<8;i++){
		SPI_SCK_CLR(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		if(regAddr&0x80){
			SPI_SDI_SET(spi_bus_t->sdi_pin);
		}
		else{
			SPI_SDI_CLR(spi_bus_t->sdi_pin);
		}
		SPI_SCK_SET(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		regAddr<<=1;
	}
	
	for(i=0;i<8;i++){	
		SPI_SCK_CLR(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		if(data&0x80){
			SPI_SDI_SET(spi_bus_t->sdi_pin);
		}
		else{
			SPI_SDI_CLR(spi_bus_t->sdi_pin);
		}
		SPI_SCK_SET(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		data<<=1;
	}
	SPI_SCK_CLR(spi_bus_t->clk_pin);
	Delay_us(spi_bus_t->delay_us);
	SPI_CS_SET(spi_bus_t->cs_pin);
}

uint8_t drv_soft_spi_read_byte(Drv_Soft_Spi_Bus *spi_bus,uint8_t regAddr){
	STRUCT(Drv_Soft_Spi_Bus) *spi_bus_t = (STRUCT(Drv_Soft_Spi_Bus) *)spi_bus;
	
	uint8_t i=0,temp=0;
	regAddr=regAddr<<1;
	regAddr=regAddr|0x01;
	SPI_CS_CLR(spi_bus_t->cs_pin);
	SPI_SCK_CLR(spi_bus_t->clk_pin);
	Delay_us(spi_bus_t->delay_us);
	for(i=0;i<8;i++){
		if(regAddr&0x80){
			SPI_SDI_SET(spi_bus_t->sdi_pin);
		}
		else{
			SPI_SDI_CLR(spi_bus_t->sdi_pin);
		}
		SPI_SCK_CLR(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		SPI_SCK_SET(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		regAddr<<=1;
	}
	for(i=0;i<8;i++){
		temp<<=1;
		SPI_SCK_CLR(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		SPI_SCK_SET(spi_bus_t->clk_pin);
		Delay_us(spi_bus_t->delay_us);
		if(SPI_SDO_READ(spi_bus_t->sdo_pin)){
			temp|=0x01;
		}
	}
	SPI_SCK_CLR(spi_bus_t->clk_pin);
	SPI_CS_SET(spi_bus_t->cs_pin);
	
	return temp;
}

int8_t drv_soft_spi_register(Drv_Soft_Spi_Bus *spi_bus,uint32_t cs_pin,uint32_t clk_pin,uint32_t sdi_pin,uint32_t sdo_pin,uint8_t  delay_us){
	STRUCT(Drv_Soft_Spi_Bus) *spi_bus_t = (STRUCT(Drv_Soft_Spi_Bus) *)spi_bus;
	spi_bus_t->cs_pin = cs_pin;
	Delay_us(1);
	spi_bus_t->clk_pin = clk_pin;
	Delay_us(1);
	spi_bus_t->sdi_pin = sdi_pin;
	Delay_us(1);
	spi_bus_t->sdo_pin = sdo_pin;
	Delay_us(1);
	spi_bus_t->delay_us = delay_us;
	
	hc32_pin_mode(cs_pin,PIN_MODE_OUTPUT_PULLUP);
	hc32_pin_mode(clk_pin,PIN_MODE_OUTPUT_PULLUP);
	hc32_pin_mode(sdi_pin,PIN_MODE_OUTPUT_PULLUP);
	hc32_pin_mode(sdo_pin,PIN_MODE_INPUT_PULLUP);
	
	return 0;
}
